<template>
  <view
    class="content"
    :style="{
      backgroundImage: `url(${template.pic})`,
    }"
  >
    <view class="page-title">
      <text class="main-text">{{ template.title }}</text>
      <text class="sub-text">{{ template.subTitle }}</text>
    </view>
    <view class="box-content">
      <view class="box-info">
        <view class="circle circle-left"></view>
        <view class="border"></view>
        <view class="circle circle-right"></view>
        <view class="box-title">
          <view class="min-circle"></view>
          <text>学生身份证拍照识别</text>
        </view>
        <view class="idcard-text">
          <text
            >扫描身份证人像面直接识别相关信息。无身份证学生可手动录入，录完请认真检查有无录错。</text
          >
        </view>
        <view class="idcard-img">
          <view class="idcard-img-content" @click="chooseImage">
            <image
              :src="idcardUrl ? idcardUrl : '../../static/idcard.jpg'"
            ></image>
          </view>
        </view>
        <Button type="primary" block color="#01C1B0" @click="pickInfomation">
          <view class="idcard-btn">
            <image src="../../static/icon.jpg"></image>
            识别身份证人像面
          </view>
        </Button>
      </view>
    </view>
    <view class="box-content">
      <view class="form-info">
        <view class="circle circle-left"></view>
        <view class="border"></view>
        <view class="circle circle-right"></view>
        <view class="box-title">
          <view class="min-circle padding"></view>
          <text>信息填写</text>
        </view>
        <view class="form-content">
          <Form ref="formRef" label-align="top" @submit="onSubmit">
            <CellGroup inset>
              <Field
                label="报考编号"
                v-model="form.registrationNumber"
                readonly
                name="registrationNumber"
                placeholder="自动生成无需填写"
              />
              <Field
                required
                label="姓名"
                v-model="form.username"
                name="username"
                placeholder="请填写姓名"
                :rules="[{ required: true, message: '请填写姓名' }]"
              />
              <Field
                required
                label="身份证号"
                v-model="form.identityCard"
                name="validatorIdcard"
                placeholder="请输入身份证号"
                :rules="[
                  { validator: validatorIdcard, message: '请输入正确身份证号' },
                ]"
              />
              <Field
                required
                label="学号"
                v-model="form.stuNumber"
                name="validatorStuId"
                placeholder="请输入学生证号"
                :rules="[
                  { validator: validatorStuId, message: '请输入学生证号' },
                ]"
              />
              <Field
                required
                label="学制"
                v-model="form.schoolSystem"
                is-link
                readonly
                name="schoolSystem"
                placeholder="请选择"
                :rules="[{ required: true, message: '请选择学制' }]"
                @click="showPicker = true"
              />
              <Popup v-model:show="showPicker" position="bottom">
                <Picker
                  :columns="eduSystemOptions"
                  @confirm="onConfirm"
                  @cancel="showPicker = false"
                />
              </Popup>
              <Field
                required
                label="性别"
                v-model="form.gender"
                is-link
                readonly
                name="gender"
                placeholder="请选择"
                @click="showGender = true"
                :rules="[{ required: true, message: '请选择性别' }]"
              />
              <Popup v-model:show="showGender" position="bottom">
                <Picker
                  :columns="genderOptions"
                  @confirm="onConfirmGender"
                  @cancel="showGender = false"
                />
              </Popup>
              <Field
                required
                label="家长（监护人）手机号"
                v-model="form.parentPhone"
                name="validatorPhone"
                placeholder="请输入手机号"
                :rules="[
                  { validator: validatorPhone, message: '请输入手机号' },
                ]"
              />
              <Field
                required
                label="出生日期"
                v-model="form.birthday"
                placeholder="请选择身份证上出生日期"
                :rules="[{ required: true, message: '请选择身份证上出生日期' }]"
                is-link
                readonly
                name="birthday"
                @click="showdatePicker = true"
              />
              <Popup v-model:show="showdatePicker" position="bottom">
                <DatePicker
                  @confirm="onConfirmDate"
                  :min-date="minDate"
                  @cancel="showdatePicker = false"
                />
              </Popup>
              <Field
                required
                label="学生性质"
                v-model="form.studentNature"
                is-link
                readonly
                name="studentNature"
                placeholder="请选择"
                :rules="[{ required: true, message: '请选择学生性质' }]"
                @click="showNature = true"
              />
              <Popup v-model:show="showNature" position="bottom">
                <Picker
                  :columns="natureOptions"
                  @confirm="onConfirmNature"
                  @cancel="showNature = false"
                />
              </Popup>
              <Field
                required
                label="联系地址"
                v-model="form.address"
                name="address"
                placeholder="请输入联系地址"
                :rules="[{ required: true, message: '请输入联系地址' }]"
              />
              <Field
                required
                label="城市生"
                v-model="form.cityBorn"
                is-link
                readonly
                name="cityBorn"
                placeholder="请选择"
                @click="showUrban = true"
                :rules="[{ required: true, message: '请选择城市生' }]"
              />
              <Popup v-model:show="showUrban" position="bottom">
                <Picker
                  :columns="urbanOptions"
                  @confirm="onConfirmUrban"
                  @cancel="showUrban = false"
                />
              </Popup>
              <Field
                required
                label="毕业学校"
                v-model="form.graduateSchool"
                name="graduateSchool"
                placeholder="请输入毕业学校全称"
                :rules="[{ required: true, message: '请输入毕业学校全称' }]"
              />
              <Field
                required
                label="是否应届"
                v-model="form.graduated"
                is-link
                readonly
                name="graduated"
                placeholder="请选择"
                @click="showGraduate = true"
                :rules="[{ required: true, message: '请选择是否应届' }]"
              />
              <Popup v-model:show="showGraduate" position="bottom">
                <Picker
                  :columns="graduateOptions"
                  @confirm="onConfirmGraduate"
                  @cancel="showGraduate = false"
                />
              </Popup>
              <Field
                required
                label="招生老师"
                v-model="form.teacherName"
                name="teacherName"
                placeholder="请输入负责招你进校的老师全名"
                :rules="[{ required: true, message: '请输入招生老师' }]"
              />
              <Field
                required
                label="报读专业"
                v-model="form.major"
                is-link
                readonly
                name="major"
                placeholder="请选择"
                @click="handleMajorPlane"
                :rules="[{ required: true, message: '请选择报读专业' }]"
              />
              <ActionSheet
                z-index="9999"
                v-model:show="showMajor"
                title=""
                :closeable="false"
              >
                <div class="sheet-content">
                  <text class="sheet-clear" @click="clear">清空</text>
                  <view>
                    <Search
                      v-model="sheetValue"
                      placeholder=""
                      :clearable="false"
                      @search="searchMajor"
                    />
                  </view>
                  <view class="radio-content">
                    <RadioGroup v-model="sheetRadio" shape="dot">
                      <Radio
                        :name="item.value"
                        checked-color="#01C1B0"
                        icon-size="32rpx"
                        v-for="item in filterOptions"
                        :key="item.value"
                        >{{ item.text }}</Radio
                      >
                    </RadioGroup>
                  </view>
                  <Button
                    type="primary"
                    block
                    color="#01C1B0"
                    @click="submitMajor"
                    >提交</Button
                  >
                </div>
              </ActionSheet>
              <Field
                required
                label="承诺书"
                name="files"
                :rules="[{ required: true, message: '请上传承诺书' }]"
              >
                <template #input>
                  <Uploader
                    accept=""
                    :max-count="1"
                    v-model="form.files"
                    :after-read="FileUpload"
                  />
                </template>
              </Field>
            </CellGroup>
            <view class="tip-info"
              >以上所有内容请认真检查核对，核对无误后点击下方按钮提交，提交后不能修改。</view
            >
          </Form>
        </view>
      </view>
    </view>
    <Button type="primary" block color="#01C1B0" @click="onValidate"
      >提交</Button
    >
  </view>
</template>

<script setup lang="ts">
import { ref, reactive } from "vue";
import {
  Button,
  Form,
  Field,
  CellGroup,
  Popup,
  Picker,
  DatePicker,
  ActionSheet,
  Search,
  RadioGroup,
  Radio,
  Uploader,
  showFailToast,
} from "vant";
import type { PickerOption, FormInstance, UploaderFileListItem } from "vant";
import { onShow, onLoad } from "@dcloudio/uni-app";
import { BAIDU_CLIENT_ID, BAIDU_CLIENT_SECRET } from "../../utils/config";

type FormType = {
  registrationNumber: string;
  username: string;
  identityCard: string;
  stuNumber: string;
  schoolSystem: string;
  gender: number | string;
  parentPhone: string;
  birthday: string;
  studentNature: string;
  address: string;
  cityBorn: string;
  graduateSchool: string;
  graduated: string;
  teacherName: string;
  major: string;
  files: Array<UploaderFileListItem>;
  promiseLetterUrl: string;
  schoolSystemId: string;
  genderId: string;
  studentNatureId: string;
  majorId: string;
};

type Params = {
  id: string;
  templateId: string;
};

type MajorType = {
  templateId: string;
  schoolSystem?: string;
};

type FileType = {
  file: File,
  objectUrl: string
}

let accessToken = ref("");

// 百度云获取accessToken
const getAccessToken = () => {
  // 请求
  uni.request({
    url: "/baiduApi/oauth/2.0/token",
    data: {
      grant_type: "client_credentials",
      client_id: BAIDU_CLIENT_ID,
      client_secret: BAIDU_CLIENT_SECRET,
    },
    dataType: "JSONP",
    method: "POST",
    header: {
      "Content-Type": "application/x-www-form-urlencoded",
    },
    success: (res: any) => {
      // 将得到的res先转对象，在.点出我们想要的值
      accessToken.value = JSON.parse(res.data).access_token;
    },
    fail(err) {},
  });
};

let loginData: Params = reactive({
  id: "",
  templateId: "",
});

onLoad((option: any) => {
  getAccessToken();
  // 获取登录页传递的参数
  loginData.id = option.id;
  loginData.templateId = option.templateId;
});

const idcardBase64 = ref("");
const idcardUrl = ref("");

// 选择身份证图片
const chooseImage = () => {
  uni.chooseImage({
    count: 1,
    success: function (res) {
      // 将图片本地路径转成base64
      toBase64((res.tempFilePaths as string[])[0]).then((res) => {
        // 可以进行识别别身份证操作 用到OCR百度云的接口
        idcardBase64.value = res;
      });
      let path = (res.tempFilePaths as string[])[0];
      idcardUrl.value = path;
    },
  });
};

// 转换为base64的函数
const toBase64 = (path: string) => {
  return new Promise<string>((resolve, reject) => {
    uni.request({
      url: path,
      responseType: "arraybuffer",
      success: (res: any) => {
        resolve(uni.arrayBufferToBase64(res.data));
      },
    });
  });
};

// 调用识别身份证正面的接口
const pickInfomation = () => {
  if (!idcardBase64.value) {
    showFailToast("请先上传身份证人像面图片");
    return;
  }
  uni.showLoading({
    title: "正在识别中...",
  });
  uni.request({
    url: "/baiduApi/rest/2.0/ocr/v1/idcard",
    data: {
      image: idcardBase64.value, // 图片的base64路径
      access_token: accessToken.value, // Access Token
      id_card_side: "front", // front身份证正面 back身份证反面
    },
    method: "POST",
    header: {
      "Content-Type": "application/x-www-form-urlencoded",
    },
    success: (res) => {
      uni.hideLoading();
      let idcardInfo: any = res.data; // 调用百度云OCR接口成功返回的值
      if (idcardInfo.error_code) {
        showFailToast("识别错误");
        return;
      }
      if (idcardInfo.image_status !== "normal") {
        showFailToast("请上传身份证人像面图片");
        return;
      }
      // 更新表单的数据
      form.username = idcardInfo.words_result["姓名"].words;
      form.identityCard = idcardInfo.words_result["公民身份号码"].words;
      form.gender = idcardInfo.words_result["性别"].words;
      const RE_DATE = /(\d{4})(\d{2})(\d{2})/;
      let birthday = idcardInfo.words_result["出生"].words;
      const matchObj: any = RE_DATE.exec(birthday);
      const year = matchObj[1];
      const month = matchObj[2];
      const day = matchObj[3];
      form.birthday = `${year}/${month}/${day}`;
    },
    fail(err) {
      uni.hideLoading();
    },
  });
};

const form: FormType = reactive({
  registrationNumber: "",
  username: "",
  identityCard: "",
  stuNumber: "",
  schoolSystem: "",
  gender: "",
  parentPhone: "",
  birthday: "",
  studentNature: "",
  address: "",
  cityBorn: "",
  graduateSchool: "",
  graduated: "",
  teacherName: "",
  major: "",
  files: [],
  promiseLetterUrl: "",
  schoolSystemId: "",
  genderId: "",
  studentNatureId: "",
  majorId: "",
});

// 校验函数
const validatorIdcard = (val: string) =>
  /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/.test(
    val
  );

const validatorPhone = (val: string) =>
  /^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/.test(
    val
  );

const validatorStuId = (val: string) => /^[1-9]\d*$/.test(val);

const formRef = ref<FormInstance>();
const onValidate = () => {
  formRef.value?.submit();
};

// 上传文件
const FileUpload = async (file: FileType) => {
  uni.showLoading({
    title: "上传中"
  });
  uni.uploadFile({
    url: "/api/anon/common/upload",
    file: file?.file, // 这里需要取里面的file
    filePath: file.objectUrl,
    name: "file",
    success: (uploadFileRes: any) => {
      uni.hideLoading();
      const { data } = JSON.parse(uploadFileRes.data);
      form.promiseLetterUrl = data;
    },
  });
};


// 提交表单
const onSubmit = (val: any) => {
  // 调用提交接口
  // 性别需要修改成数字类型
  // 文件需要修改
  let data = {
    id: loginData.id,
    templateId: loginData.templateId,
    dataExtra: {
      registrationNumber: form.registrationNumber,
      username: form.username,
      identityCard: form.identityCard,
      stuNumber: form.stuNumber,
      schoolSystem: form.schoolSystemId,
      gender: form.genderId,
      parentPhone: form.parentPhone,
      birthday: form.birthday,
      studentNature: form.studentNatureId,
      address: form.address,
      cityBorn: form.cityBorn === "是" ? true : false,
      graduateSchool: form.graduateSchool,
      graduated: form.graduated === "是" ? true : false,
      teacherName: form.teacherName,
      majorId: form.majorId,
      promiseLetterUrl: form.promiseLetterUrl,
    },
  }
  uni.request({
    url: "/api/anon/fill/saveFillData",
    data,
    header: {
      "Content-Type": "application/json", //自定义请求头信息
    },
    method: "POST",
    success: (res: any) => {
      const { code } = res.data;
      if (code === 200) {
        uni.showToast({
          title: "填报成功",
        });
      } else {
        showFailToast("填报失败");
      }
    },
  });
};

const eduSystemOptions: PickerOption[] = [
  { text: "两年制", value: 2 },
  { text: "三年制", value: 3 },
  { text: "四年制", value: 4 },
  { text: "五年制", value: 5 },
];
const genderOptions: PickerOption[] = [
  { text: "男", value: 1 },
  { text: "女", value: 2 },
];
const natureOptions: PickerOption[] = [
  { text: "群众", value: 1 },
  { text: "团员", value: 2 },
  { text: "党员", value: 3 },
];
const urbanOptions: PickerOption[] = [
  { text: "是", value: "是" },
  { text: "否", value: "否" },
];
const graduateOptions: PickerOption[] = [
  { text: "是", value: "是" },
  { text: "否", value: "否" },
];
let majorOptions = ref<PickerOption[]>([]);

const minDate = ref(new Date(1960, 0, 1));

const showPicker = ref(false);
const onConfirm = (selected: any) => {
  form.schoolSystem = selected?.selectedOptions?.[0]?.text;
  form.schoolSystemId = selected?.selectedOptions?.[0]?.value;
  showPicker.value = false;
  getMajorOptions();
};
// 根据学制获取专业
const getMajorOptions = () => {
  let params: MajorType = {
    templateId: loginData.templateId,
  };
  if (form.schoolSystem) {
    params.schoolSystem = form.schoolSystem;
  }
  uni.request({
    url: "/api/anon/fill/listFillMajor",
    data: params,
    header: {
      "Content-Type": "application/json",
    },
    method: "GET",
    success: (res: any) => {
      const { code, data } = res.data;
      if (code === 200) {
        majorOptions.value = data.map((i: any) => ({
          text: i.majorName,
          value: i.id,
        }));
        filterOptions.value = majorOptions.value;
      }
    },
  });
};

const showGender = ref(false);
const onConfirmGender = (selected: any) => {
  form.gender = selected?.selectedOptions?.[0]?.text;
  form.genderId = selected?.selectedOptions?.[0]?.value;
  showGender.value = false;
};

const showNature = ref(false);
const onConfirmNature = (selected: any) => {
  form.studentNature = selected?.selectedOptions?.[0]?.text;
  form.studentNatureId = selected?.selectedOptions?.[0]?.value;
  showNature.value = false;
};

const showUrban = ref(false);
const onConfirmUrban = (selected: any) => {
  form.cityBorn = selected?.selectedOptions?.[0]?.text;
  showUrban.value = false;
};

const showGraduate = ref(false);
const onConfirmGraduate = (selected: any) => {
  form.graduated = selected?.selectedOptions?.[0]?.text;
  showGraduate.value = false;
};

const showdatePicker = ref(false);
const onConfirmDate = (selected: any) => {
  form.birthday = selected?.selectedValues.join("/");
  showdatePicker.value = false;
};
const showMajor = ref(false);
const clear = () => {
  sheetValue.value = "";
  filterOptions.value = majorOptions.value;
};
let filterOptions = ref<PickerOption[]>([]);

const searchMajor = (val: string) => {
  filterOptions.value = majorOptions.value.filter((i: any) =>
    i.text.includes(val)
  );
};
const handleMajorPlane = () => {
  showMajor.value = true;
  sheetRadio.value = majorOptions.value.find((i) => i.text === form.major)
    ?.value as string;
};
const sheetValue = ref("");
const sheetRadio = ref("");

const submitMajor = () => {
  form.major = majorOptions.value.find((i) => i.value === sheetRadio.value)
    ?.text as string;
  form.majorId = sheetRadio.value;
  showMajor.value = false;
};

const template = reactive({
  id: "",
  title: "",
  subTitle: "",
  pic: "",
  startTime: "",
  endTime: "",
});
// 获取模板详情
const getTemplateDetail = () => {
  uni.request({
    url: "/api/anon/fill/getFillTemplateDetail",
    data: {
      templateId: loginData.templateId,
    },
    header: {
      "Content-Type": "application/json",
    },
    method: "GET",
    success: (res: any) => {
      const { code, data } = res.data;
      if (code === 200) {
        template.id = data.id;
        template.title = data.title;
        template.subTitle = data.subTitle;
        template.pic = data.pic;
        template.startTime = data.startTime;
        template.endTime = data.endTime;
        // 修改标题
        uni.setNavigationBarTitle({
          title: template.subTitle,
        });
      }
    },
  });
};

onShow(() => {
  getTemplateDetail();
  getMajorOptions();
});
</script>

<style lang="less">
.content {
  padding: 30rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-repeat: no-repeat;
  background-size: 100%;
  .page-title {
    display: flex;
    align-items: center;
    flex-direction: column;
    .main-text {
      font-size: 54rpx;
      margin: 100rpx 50rpx 50rpx;
      text-shadow: 1px 2px 2px #165cc5;
      color: #ffffff;
    }
    .sub-text {
      font-size: 30rpx;
      margin-bottom: 300rpx;
      text-shadow: 1px 2px 2px #4073be;
      color: #ffffff;
    }
  }
  .tip-info {
    color: #ff795f;
    padding: 20rpx 30rpx 10rpx 50rpx;
  }
  .radio-content {
    max-height: 560rpx;
    overflow: auto;
    margin-bottom: 20rpx;
  }
}
.box-content {
  width: calc(100% - 60rpx);
  min-height: 300rpx;
  border-radius: 20rpx;
  padding: 25rpx;
  background: rgba(1, 193, 176, 0.5);
  display: flex;
  margin-bottom: 40rpx;
}
.box-title {
  display: flex;
  align-items: center;
}
.min-circle {
  width: 15rpx;
  height: 15rpx;
  border-radius: 50%;
  background: #ffc53e;
  margin-right: 20rpx;
}
.border {
  width: calc(100% - 20rpx);
  height: 1px;
  border-bottom: 1px dashed #efefef;
  position: absolute;
  top: 85rpx;
  left: 10rpx;
}
.box-info {
  flex: 1;
  background: #ffffff;
  border-radius: 20rpx;
  padding: 30rpx 40rpx 50rpx 40rpx;
  position: relative;
}
.padding {
  margin-left: 40rpx;
}
.form-info {
  flex: 1;
  background: #ffffff;
  border-radius: 20rpx;
  padding: 30rpx 0 50rpx 0;
  position: relative;
}
.circle {
  width: 20rpx;
  height: 20rpx;
  border-radius: 50%;
  background: rgba(1, 193, 176, 0.5);
  position: absolute;
  top: 80rpx;
}
.circle-left {
  left: -10rpx;
  clip: rect(0rpx 20rpx 20rpx 10rpx);
}
.circle-right {
  right: -10rpx;
  clip: rect(0rpx 10rpx 20rpx 0rpx);
}
.idcard-text {
  color: #9fa6b2;
  margin-top: 45rpx;
}
.idcard-img {
  height: 260rpx;
  padding: 20rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  &-content {
    width: 300rpx;
    height: 200rpx;
    border-radius: 20rpx;
    background: #fafafa;
    display: flex;
    align-items: center;
    justify-content: center;
    uni-image {
      width: 80%;
      height: 82%;
    }
  }
}
.idcard-btn {
  display: flex;
  align-items: center;
  uni-image {
    width: 70rpx;
    height: 50rpx;
    margin-right: 22rpx;
  }
}
.form-content {
  margin-top: 50rpx;
  /deep/ .van-field__label--required {
    &:before {
      content: "";
    }
    &:after {
      margin-left: 4rpx;
      color: var(--van-field-required-mark-color);
      content: "*";
    }
  }
}
.sheet-content {
  display: flex;
  flex-direction: column;
  padding: 25rpx 35rpx;
  .sheet-clear {
    color: #ff7155;
    margin-bottom: 20rpx;
  }
  /deep/ .van-radio-group {
    margin: 25rpx 0;
  }
  /deep/ .van-radio {
    margin-bottom: 40rpx;
  }
  /deep/ .van-radio[aria-checked="true"] {
    .van-radio__label {
      color: #01c1b0;
    }
  }
  /deep/ .van-search {
    padding: 20rpx 0;
  }
  /deep/ .van-field__label--top {
    width: auto;
  }
}
</style>
